package com.bicon.base.data.common;

import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPConnectionClosedException;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import sun.net.ftp.FtpClient;
import sun.net.ftp.FtpProtocolException;

/**
 * ftp上传下载
 * 
 * @author dao
 * 
 */
public class FtpUtil {
	private static Logger logger = LoggerFactory.getLogger(FtpUtil.class);

	private  FtpClient ftpClient = null;

	/**
	 * 构造方法，新建一个FtpClient对象，并打开FTP服务器
	 * 
	 * @param host
	 *            FTP服务器地址；port FTP服务端口
	 * @return
	 * 
	 */
	public FtpUtil(String host, int port) throws IOException {
		try {
			ftpClient = FtpClient.create(host);
		} catch (FtpProtocolException e) {
			e.printStackTrace();
		}
	}

	public FtpUtil() {

	}

	/**
	 * 登录方法，通过用户名密码登录到指定的FTP服务器上去，并返回欢迎信息
	 * 
	 * @param username
	 *            FTP用户名；password 密码
	 * 
	 */
	public String login(String username, String password) throws IOException {
		try {
			this.ftpClient.login(username, null, password);
		} catch (FtpProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return this.ftpClient.getWelcomeMsg();
	}

	/**
	 * 关闭FTP连接
	 */
	private void close() {
		if (ftpClient != null) {
			try {
				ftpClient.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * ftp上传文件
	 * 
	 * @param fileName
	 *            上传文件名
	 * @param filePath
	 *            上传本地路径
	 * @return
	 * @throws SocketException
	 * @throws IOException
	 * @throws FtpProtocolException
	 */
	public boolean uploadFile(String fileName, String filePath)
			throws SocketException, IOException, FtpProtocolException {
		boolean flag = false;
		File file = new File(filePath + "\\" + fileName);
		if (file.length() == 0 || !file.isFile()) {
			return false;
		}
		ftpClient.setBinaryType();
		OutputStream os = null;
		FileInputStream is = null;
		try {
			os = ftpClient.putFileStream(fileName, true);
			java.io.File file_in = new java.io.File(filePath + "\\" + fileName);
			if (file_in.length() == 0) {
				logger.info("upload file is empty");
			}
			is = new FileInputStream(file_in);
			byte[] bytes = new byte[1024];
			int c;
			while ((c = is.read(bytes)) != -1) {
				os.write(bytes, 0, c);
			}
			flag = true;
		} finally {
			if (is != null) {
				is.close();
			}
			if (os != null) {
				os.close();
			}
		}
		this.ftpClient.setAsciiType();
		return flag;
	}

	/**
	 * ftp上传文件
	 * 
	 * @param fileName
	 *            文件名
	 * @param in
	 *            上传文件流
	 * @param ip
	 *            ip地址
	 * @param port
	 *            端口号
	 * @param userName
	 *            登录名
	 * @param passWord
	 *            登录密码
	 * @return
	 * @throws FtpRemotePathNotExistException
	 *             FTP服务器上找不到路径
	 */
	public static boolean uploadFile(String fileName, String ip, int port, String userName, String passWord,
			String upLoadPath, InputStream in) throws Exception {
		boolean flag = false;
		FTPClient ftpClient = new FTPClient();
		// windows下默认为gbk Linux下设置本地编码 windows下也可以设置成utf-8
		ftpClient.setControlEncoding("GBK");
		ftpClient.connect(ip, port);
		ftpClient.login(userName, passWord);
		boolean change = ftpClient.changeWorkingDirectory(upLoadPath);
		if (!change) {
			logger.error("FTP uploadPath is not exist: " + upLoadPath);
		}
		ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
		flag = ftpClient.storeFile(fileName, in);
		in.close();
		ftpClient.logout();
		return flag;
	}

	/**
	 * ftp上传文件
	 * 
	 * @param fileName
	 *            文件名
	 * @param filePath
	 *            上传路径
	 * @param ip
	 *            ip地址
	 * @param port
	 *            端口号
	 * @param userName
	 *            登录名
	 * @param passWord
	 *            登录密码
	 * @return
	 * 
	 * 
	 * 上传使用类
	 **/
	public boolean uploadFile(String fileName, String filePath, String ip, int port, String userName, String passWord,
			String upLoadPath) {
		boolean flag = false;
		FTPClient ftpClient = new FTPClient();
		InputStream fis = null;
		// windows下默认为gbk Linux下设置本地编码 windows下也可以设置成utf-8
		try {
			ftpClient.enterLocalPassiveMode();
			ftpClient.setControlEncoding("UTF-8");
			ftpClient.connect(ip, port);
			ftpClient.login(userName, passWord);
			ftpClient.enterLocalPassiveMode();
			ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
			ftpClient.changeWorkingDirectory(upLoadPath);
			fis = new FileInputStream(new File(filePath + File.separator + fileName));
			flag = ftpClient.storeFile(fileName, fis);
			fis.close();
			ftpClient.logout();
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
		   try{
			   if(null != fis){
				   fis.close();
			   }
			   if(null != ftpClient){
				   ftpClient.logout();
			   }
		   }catch(Exception ex){
			   
		   }
		}
		return flag;
	}

	/**
	 * ftp上传文件
	 * 
	 * @param fileName
	 *            文件名
	 * @param uploadPath
	 *            上传路径
	 * @param message
	 *            报文
	 * @param host
	 * @param port
	 * @param username
	 * @param password
	 * @return
	 */
	public boolean uploadFile(String fileName, String uploadPath, String message, String host, int port,
			String username, String password) {
		boolean flag = false;
		boolean login = false;
		OutputStream out = null;
		BufferedOutputStream bos = null;
		FTPClient ftpClient = null;
		try {
			ftpClient = new FTPClient();
			ftpClient.setControlEncoding("utf-8");
			ftpClient.connect(host, port);
			login = ftpClient.login(username, password);
			if (!login) {
				return flag;
			}
			boolean change = ftpClient.changeWorkingDirectory(uploadPath);
			if (!change) {
				return flag;
			}
			ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
			out = ftpClient.storeFileStream(fileName);
			if (out != null) {
				bos = new BufferedOutputStream(out);
				bos.write(message.getBytes());
				bos.flush();
				flag = true;
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (out != null) {
					out.close();
					if (bos != null) {
						bos.close();
					}
				}
				if (login) {
					ftpClient.logout();// 需在文件流关闭之后才能退出登录
					ftpClient.disconnect();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return flag;
	}

	/**
	 * ftp文件下载
	 * 
	 * @param fileName
	 *            文件名
	 * @param filePath
	 *            下载到本地路径
	 * @param ip
	 *            ip地址
	 * @param port
	 *            端口号
	 * @param userName
	 *            登录名
	 * @param passWord
	 *            登录密码
	 * @param downLoadPath
	 *            ftp路径
	 * @return
	 */
	public boolean downloadFile(String fileName, String filePath, String ip, int port, String userName, String passWord,
			String downLoadPath) {
		FTPClient fTPClient = new FTPClient();
		boolean _tag = false;
		try {
			fTPClient.connect(ip, port);
			fTPClient.login(userName, passWord);
			if (!FTPReply.isPositiveCompletion(fTPClient.getReplyCode())) {
				return _tag;
			}
			// 转到指定下载目录
			fTPClient.changeWorkingDirectory(downLoadPath);

			FTPFile[] f = fTPClient.listFiles();
			for (FTPFile ftpFile : f) {
				logger.info("FTP_FILE_NAME:" + ftpFile.getName());
				if (ftpFile.getName().equals(fileName)) {
					FileOutputStream fot = new FileOutputStream(new File(filePath + "/" + ftpFile.getName()));
					_tag = fTPClient.retrieveFile(ftpFile.getName(), fot);
					fot.close();
				}
			}
			// fTPClient.logout();
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (fTPClient != null) {
				try {
					fTPClient.logout();
					fTPClient.disconnect();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return _tag;
	}

	/**
	 * 将FTP上目录中所有文件下载到本地指定目录
	 * 
	 * @param ftpPath
	 *            FTP目录
	 * @param localPath
	 *            本地目录
	 * @param ip
	 * @param port
	 * @param userName
	 * @param passWord
	 * @return
	 */
	public boolean downloadAllFile(String ftpPath, String localPath, String ip, int port, String userName,
			String passWord) {
		FTPClient fTPClient = new FTPClient();
		boolean flag = false;

		try {
			fTPClient.connect(ip, port);
			fTPClient.login(userName, passWord);
			if (!FTPReply.isPositiveCompletion(fTPClient.getReplyCode())) {
				return flag;
			}
			// 转到指定下载目录
			fTPClient.changeWorkingDirectory(ftpPath);

			FTPFile[] files = fTPClient.listFiles();
			for (FTPFile file : files) {
				String fileName = file.getName();
				OutputStream out = null;
				try {
					out = new FileOutputStream(new File(localPath, fileName));
					flag = fTPClient.retrieveFile(fileName, out);
					if (flag) {
						logger.info("download ftp file success:" + fileName);
					} else {
						logger.info("download ftp file failed:" + fileName);
						return flag;
					}
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
					if (out != null) {
						try {
							out.close();
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (fTPClient != null) {
				try {
					fTPClient.logout();
				} catch (IOException e) {
					e.printStackTrace();
				}
				try {
					fTPClient.disconnect();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return flag;
	}

	/**
	 * 返回文件流
	 * 
	 * @param fileName
	 *            文件名称
	 * @param ip
	 *            ftp地址
	 * @param port
	 *            端口号
	 * @param userName
	 *            登录名称
	 * @param passWord
	 *            登录密码
	 * @param downLoadPath
	 *            ftp下载路径
	 * @return
	 */
	public InputStream downloadFile1(String fileName, String ip, int port, String userName, String passWord,
			String downLoadPath) {
		String ip1 ="192.168.1.101";
		int port1=21;
		FTPClient fTPClient = null;
		InputStream is = null;
		try {
			fTPClient = new FTPClient();
			fTPClient.setDataTimeout(60 * 1000);// 设置传输超时时间为60秒
			// fTPClient.addProtocolCommandListener(new
			// PrintCommandListener(System.out));// FTP调试信息
			fTPClient.connect(ip1, port1);
			fTPClient.login("ftpuser", "Rxin2014");
			if (!FTPReply.isPositiveCompletion(fTPClient.getReplyCode())) {
				fTPClient.disconnect();
				return is;
			}
			// 转到指定下载目录
			fTPClient.changeWorkingDirectory(downLoadPath);
			FTPFile[] f = fTPClient.listFiles();
			for (FTPFile ftpFile : f) {
				if (ftpFile.getName().equals(fileName)) {
					is = fTPClient.retrieveFileStream(ftpFile.getName());
				}
			}
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (fTPClient.isConnected()) {
				try {
					fTPClient.disconnect();
				} catch (IOException e) {
					// do nothing
				}
			}
		}
		return is;
	}
	
	
	
	public boolean copyFile(String from,String to,String host,int port2,String userName,String passWord) throws IOException{
		boolean key = true;
		FTPClient ftpClient = new FTPClient();
		ftpClient.enterLocalPassiveMode();// 被动模式,避免Linux安全因素引起端口问题
		try { 
	        int reply; 
	        //如果采用默认端口，可以使用ftp.connect(url)的方式直接连接FTP服务器 	
	        ftpClient.connect(host,port2);
	        //登录	
	        ftpClient.login(userName, passWord);
	        reply = ftpClient.getReplyCode(); 
	        if (!FTPReply.isPositiveCompletion(reply)) { 
	        	ftpClient.disconnect(); 
	            return key; 
	        }
	        ftpClient.changeWorkingDirectory(from);//转移到FTP服务器目录 
			//复制除过脱机文件所有文件至process目录下
			FTPFile[] files1 = ftpClient.listFiles(from);
			for (FTPFile ftpFile : files1) {//复制其他文件至process目录下
					ByteArrayInputStream in = null;  
				    ByteArrayOutputStream fos = new ByteArrayOutputStream();  
				    try {  
				        ftpClient.setBufferSize(1024 * 2);  
				        // 设置以二进制流的方式传输  
				        ftpClient.setFileType(FTP.BINARY_FILE_TYPE);  
				        // 将文件读到内存中 	
				        ftpClient.retrieveFile(ftpFile.getName(), fos);  
				        in = new ByteArrayInputStream(fos.toByteArray());  
				        if (in != null) {  
				            ftpClient.changeWorkingDirectory(to);  
				            ftpClient.storeFile(ftpFile.getName(), in);
				        }  
				    } finally {  
				        // 关闭流
				        if (in != null) {  
				            in.close();
				        }  
				        if (fos != null) {  
				            fos.close();
				        }  
				    } 
			}
			ftpClient.changeWorkingDirectory(from);//转移到FTP服务器目录 
			FTPFile[] files = ftpClient.listFiles(from);
			for (FTPFile ftpFile : files) {
				ftpClient.rename(ftpFile.getName(), "../processT"+ftpFile.getName());
			}
			
		}catch (Exception e) {
			e.printStackTrace();
		}finally{
			if (ftpClient.isConnected()) { 
	            try { 
	            	ftpClient.disconnect(); 
	            } catch (IOException ioe) { 
	            } 
	        }  
		}
		return key;
}
	
	
	/**
	 *  FTP文件的移动
	 * @param args
	 * @throws SocketException 
	 * @throws IOException
	 */
	
	public boolean moveFile(String ip,int port,String username,String password,String from,String to) throws SocketException, IOException{
		FTPClient client = new FTPClient();
		boolean result = false;
		try {
			
			client.connect(ip,port);
			result = client.login(username, password);

			if (result == true) {
				System.out.println("User successfully logged in.");
			} else {
				System.out.println("Login failed!");
				return result;
			}
			// Rename file.
			
			result = client.rename(from, to);
			
			if (result == true) {
				logger.info("File renamed!");
			} else {
				logger.info("File renaming is failed.");
			}

		} catch (FTPConnectionClosedException e) {
			logger.error("",e.fillInStackTrace());
			e.printStackTrace();
		} finally {
			try {

				client.disconnect();
			} catch (Exception e) {
				logger.error("",e.fillInStackTrace());
			}
		}
		return result;
	}
	
	
	/**
	 *  本地文件的移动
	 * @param args
	 * @throws SocketException 
	 * @throws IOException
	 */
	
	public boolean moveFile(String from,String to) throws SocketException, IOException{
		File file = new File(from);
		File file2=new File(to);
		boolean result = false;
		
			// Rename file.
			
			result = file.renameTo(file2);
			
			if (result == true) {
				System.out.println("File renamed!");
			} else {
				System.out.println("File renaming is failed.");
			
		}
		return result;
	}
	
	/***
	 * 
	 * @param args
	 */
	public boolean copyDirectory( String ip,int port,String username,String password,String from, String to) {
		FTPClient ftpClient=new FTPClient();
        boolean copyFalg = false;
        
        try {
			ftpClient.connect(ip,port);
			copyFalg = ftpClient.login(username, password);
		} catch (SocketException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		if (copyFalg == true) {
			logger.info("User successfully logged in.");
		} else {
			logger.info("Login failed!");
			return copyFalg;
		}
        
        FTPFile[] filelist;
        try {
            // 枚举当前from目录所有文件+子目录
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.enterLocalPassiveMode();
            filelist = ftpClient.listFiles(from);
            int length = filelist.length;
            FTPFile ftpFile = null;
            String category = null;
            InputStream inputStream = null;
            for (int i = 0; i < length; i++) {
                ftpFile = filelist[i];
                category = ftpFile.getName();
                if (ftpFile.isFile()) {
                    // 如果是文件则复制文件
                    //long l = ftpFile.getSize();
                    //ftpClient.setRestartOffset(13000);
                    inputStream = ftpClient.retrieveFileStream(from + "/" + category);
                    // 复制文件时掉用了retrieveFileStream方法
                    // 调用完之后必须调用completePendingCommand释放,否则FTP会断开连接
                    if (!ftpClient.completePendingCommand()) {
                        copyFalg = false;
                        return copyFalg;
                    }
                    // 如果读取的文件流不为空则复制文件
                    if (inputStream != null) {
                        copyFalg = ftpClient.storeFile(to + "/" + category, inputStream);
                        // 关闭文件流
                        inputStream.close();
                        if (!copyFalg) {
                            return copyFalg;
                        }
                    }

                } else if (ftpFile.isDirectory()) {
                    // 如果是目录则先创建该目录
                    copyFalg = ftpClient.makeDirectory(to + "/" + category);
                    // 再进入子目录进行递归复制
                    copyDirectory(ip,port,username,password, from + "/" + category, to + "/" + category);
                }
            }
        } catch (IOException e) {
            logger.error("FtpClientUtil.copyDirectory failed. caused by " + e.getMessage(), e);
            copyFalg = false;
        }
        return copyFalg;

    } 

	
	
	
	public static void main(String[] args) {
		FtpUtil f = new FtpUtil();
		InputStream s = f.downloadFile1("wallet_ttlv.txt", "192.168.1.101", 21, "ftpuser", "Rxin2014",
				"/ftpuser/20140514/00001111/sourcetradefile/wallet_ttlv.txt");
		System.out.println(s);
	}
	
	
	
}
